﻿using Newtonsoft.Json;

namespace Ecobee.Net
{
	/// <summary>
	/// The function object is defined by its functionType and one or more additional properties. The property
	/// list is variable depending on the type of function. Functions are used to perform more complex operations 
	/// on a thermostat or user which are too complex with simple property modifications. Functions are used to 
	/// modify read-only objects where appropriate.
	/// </summary>
	public class Function : ApiObject
	{
		private string _type = string.Empty;
		private ApiObject _parameters = null;

		/// <summary>
		/// 
		/// </summary>
		/// <param name="type"></param>
		/// <param name="parameters"></param>
		public Function(string type, ApiObject parameters)
		{
			this.Type = type;
			this.Parameters = parameters;
		}

		/// <summary>
		/// The function type name. See the type name in the function documentation. 
		/// </summary>
		[JsonProperty(PropertyName = "type", Order = 1)]
		public string Type
		{
			get
			{
				return _type;
			}
			set
			{
				_type = value;
			}
		}

		/// <summary>
		/// A map of key=value pairs as the parameters to the function. See individual function documentation for the properties. 
		/// </summary>
		[JsonProperty(PropertyName = "params", Order = 2, DefaultValueHandling = DefaultValueHandling.Ignore)]
		public ApiObject Parameters
		{
			get
			{
				return _parameters;
			}
			set
			{
				_parameters = value;
			}
		}

		/// <summary>
		/// Pre-defined names of available thermostat functions.
		/// </summary>
		public static class FunctionNames
		{
			public static string Acknowledge = "acknowledge";
			public static string ControlPlug = "controlPlug";
			public static string CreateVacation = "createVacation";
			public static string DeleteVacation = "deleteVacation";
			public static string ResumeProgram = "resumeProgram";
			public static string SendMessage = "sendMessage";
			public static string SetHold = "setHold";
		}

		#region Pre-defined functions
		/// <summary>
		/// The acknowledge function allows an alert to be acknowledged.
		/// </summary>
		/// <param name="acknowledge"></param>
		/// <returns></returns>
		public static Function Acknowledge(Acknowledge acknowledge)
		{
			return new Function(FunctionNames.Acknowledge, acknowledge);
		}

		/// <summary>
		/// Control the on/off state of a plug by setting a hold on the plug. Creates a hold for the 
		/// on or off state of the plug for the specified duration. Note that an event is created 
		/// regardless of whether the program is in the same state as the requested state.
		/// </summary>
		public static Function ControlPlug = new Function(FunctionNames.ControlPlug, null);
		
		/// <summary>
		/// The create vacation function creates a vacation event on the thermostat. If the 
		/// start/end date/times are not provided for the vacation event, the vacation event 
		/// will begin immediately and last 14 days.
		/// </summary>
		public static Function CreateVacation = new Function(FunctionNames.CreateVacation, null);

		/// <summary>
		/// The delete vacation function deletes a vacation event from a thermostat. This is the only 
		/// way to cancel a vacation event. This method is able to remove vacation events not yet 
		/// started and scheduled in the future.
		/// </summary>
		/// <param name="vacation"></param>
		/// <returns></returns>
		public static Function DeleteVacation(Vacation vacation)
		{
			return new Function(FunctionNames.DeleteVacation, vacation);
		}

		/// <summary>
		/// The resume program function removes the currently running event providing the event is not a 
		/// mandatory demand response event. The top active event is removed from the stack and the thermostat 
		/// resumes its program, or enters the next event in the stack if one exists. This function may need 
		/// to be called multiple times in order to resume all events. Sending 3 resume functions in a row 
		/// will resume the thermostat to its program in all instances.
		/// </summary>
		/// <returns></returns>
		public static Function ResumeProgram()
		{
			return new Function(FunctionNames.ResumeProgram, null);
		}

		/// <summary>
		/// The send message function allows an alert message to be sent to the thermostat. The message 
		/// properties are same as those of the Alert Object.
		/// </summary>
		/// <param name="sendMessage"></param>
		/// <returns></returns>
		public static Function SendMessage(Message sendMessage)
		{
			return new Function(FunctionNames.SendMessage, sendMessage);
		}

		/// <summary>
		/// The set hold function sets the thermostat into a hold with the specified temperature. Creates a 
		/// hold for the specified duration. Note that an event is created regardless of whether the program 
		/// is in the same state as the requested state. To resume from a hold and return to the program, 
		/// use the ResumeProgram function.
		/// </summary>
		public static Function SetHold(Hold hold)
		{
			return new Function(FunctionNames.SetHold, hold);
		}
		#endregion
	}
}
